/*
 * @Descripttion:
 * @version: 1.0.0
 * @Date: 2021-06-30 18:14:17
 * @LastEditTime: 2022-01-11 19:38:59
 */

import { defined, Scene } from 'cesium';
import { SceneListenerType } from '../CustomCesium';

interface IListener {
  code: string;
  type: SceneListenerType;
  listener: () => void;
}

class SceneListener {
  private scene: Scene;
  private listeners: IListener[];

  constructor(scene: Scene) {
    this.scene = this.init(scene);
    this.listeners = [];
  }

  /**
   * @descripttion: 初始化
   * @param {Scene} scene 场景
   * @return {*}
   */
  private init(scene: Scene) {
    if (!defined(scene)) throw new Error('EventListener,无效的场景对象！');
    return scene;
  }

  /**
   * @descripttion: 添加监听
   * @param {IListener} listener
   * @return {*}
   */
  add(code: string, type: SceneListenerType, listener: () => void) {
    if (!this.isExists(code)) {
      switch (type) {
        case SceneListenerType.postRender:
          this.scene.postRender.addEventListener(listener);
          break;
        case SceneListenerType.postUpdate:
          this.scene.postUpdate.addEventListener(listener);
          break;
        case SceneListenerType.preRender:
          this.scene.preRender.addEventListener(listener);
          break;
        case SceneListenerType.preUpdate:
          this.scene.preUpdate.addEventListener(listener);
          break;
        default:
          break;
      }
      this.listeners.push({ code, type, listener });
    }
  }

  /**
   * @descripttion: 是否存在监听
   * @param {string} code 唯一标识
   * @return {boolean} 查询结果
   */
  isExists(code: string) {
    return this.listeners.findIndex((item) => item.code === code) >= 0;
  }

  /**
   * @descripttion: 获取图层
   * @param {string} code 图层唯一标识
   * @return {LayerRecord} 图层记录
   */
  get(code: string) {
    if (this.isExists(code)) return this.listeners.filter((item) => item.code === code)[0];
  }

  /**
   * @descripttion: 删除图层
   * @param {string} code 图层唯一索引
   * @return {void}
   */
  removeByCode(code: string) {
    let result = false;
    if (this.isExists(code)) {
      const { listener, type } = this.get(code)!;
      switch (type) {
        case SceneListenerType.postRender:
          this.scene.postRender.removeEventListener(listener);
          break;
        case SceneListenerType.postUpdate:
          this.scene.postUpdate.removeEventListener(listener);
          break;
        case SceneListenerType.preRender:
          this.scene.preRender.removeEventListener(listener);
          break;
        case SceneListenerType.preUpdate:
          this.scene.preUpdate.removeEventListener(listener);
          break;
        default:
          break;
      }
      const newListeners = this.listeners.filter((item) => item.code !== code);
      this.listeners = [...newListeners];
      result = true;
    }
    return result;
  }
}
export default SceneListener;
